import service
import form
import blue
import uix
import uiutil
import xtriui
import base
import uthread
import state
import util
import draw
import trinity
import sys
import fleetbr
import math
import stackless
import log
import uiconst
SHOW_NONE = -1
SHOW_DEFAULT = 0
SHOW_ALL = 1

class BracketMgr(service.Service):
    __guid__ = 'svc.bracket'
    __update_on_reload__ = 0
    __exportedcalls__ = {'GetBracketName': [],
     'GetBracketName2': [],
     'SetBracketName': [],
     'ResetOverlaps': [],
     'CheckOverlaps': [],
     'CleanUp': [],
     'ClearBracket': [],
     'ShowAll': [],
     'ShowNone': [],
     'ShowingAll': [],
     'ShowingNone': [],
     'GetBracketProps': [],
     'Reload': [],
     'GetScanSpeed': [],
     'GetCaptureData': []}
    __notifyevents__ = ['DoBallsAdded',
     'DoBallRemove',
     'DoBallClear',
     'ProcessSessionChange',
     'OnStateChange',
     'OnDestinationSet',
     'OnPostCfgDataChanged',
     'OnBallparkCall',
     'OnSlimItemChange',
     'OnAttribute',
     'OnAttributes',
     'OnCaptureChanged',
     'OnBSDTablesChanged']
    __dependencies__ = ['michelle',
     'tactical',
     'map']

    def __init__(self):
        service.Service.__init__(self)
        self.unwantedBracketGroups = [const.groupSecondarySun]



    def Run(self, memStream = None):
        service.Service.Run(self, memStream)
        self.scenarioMgr = sm.StartService('scenario')
        self.SetupBracketTemplate()
        self.Reload()



    def SetupBracketTemplate(self):
        self.bracketTemplate = xtriui.Bracket(trinity.UIBracket())
        self.bracketTemplate.name = '__inflightbracket'
        self.bracketTemplate.align = uix.UI_ALABSOLUTE
        self.bracketTemplate.state = uix.UI_PICKCHILDREN
        self.bracketTemplate.width = self.bracketTemplate.height = 16



    def Stop(self, stream):
        self.CleanUp()



    def CleanUp(self):
        self.shipLabels = None
        self.brackets = {}
        self.updateBrackets = []
        self.cat_mapping = {}
        self.grp_mapping = {}
        self.type_mapping = {}
        self.overlaps = []
        self.overlapsHidden = []
        self.checkingOverlaps = 0
        self.gotProps = 0
        self.updatingAll = 0
        self.showallTimer = None
        self.showHiddenTimer = None
        self.updatelazy = None
        uix.Flush(uicore.layer.bracket)



    def Hide(self):
        l_bracket = uicore.layer.bracket
        if l_bracket:
            l_bracket.state = uix.UI_HIDDEN



    def Show(self):
        l_bracket = uicore.layer.bracket
        if l_bracket:
            l_bracket.state = uix.UI_PICKCHILDREN



    def Reload(self):
        self.showState = SHOW_DEFAULT
        self.specials = (const.groupLargeCollidableStructure, const.groupMoon)
        self.bypassFilter = False
        self.CleanUp()
        ballPark = sm.GetService('michelle').GetBallpark(doWait=True)
        if not ballPark:
            return 
        lst = []
        for (ballID, ball,) in ballPark.balls.iteritems():
            slimItem = ballPark.GetInvItem(ballID)
            if slimItem:
                lst.append((ball, slimItem))

        self.DoBallsAdded(lst, ignoreAsteroids=False)



    def SetupProps(self):
        self.npcSpecial = [const.groupConcordDrone,
         const.groupConvoy,
         const.groupConvoyDrone,
         const.groupCustomsOfficial,
         const.groupFactionDrone,
         const.groupMissionDrone,
         const.groupPirateDrone,
         const.groupPoliceDrone,
         const.groupRogueDrone,
         const.groupStorylineBattleship,
         const.groupStorylineFrigate,
         const.groupStorylineCruiser,
         const.groupStorylineMissionBattleship,
         const.groupStorylineMissionFrigate,
         const.groupStorylineMissionCruiser,
         const.groupAsteroidAngelCartelBattleCruiser,
         const.groupAsteroidAngelCartelBattleship,
         const.groupAsteroidAngelCartelCruiser,
         const.groupAsteroidAngelCartelDestroyer,
         const.groupAsteroidAngelCartelFrigate,
         const.groupAsteroidAngelCartelHauler,
         const.groupAsteroidAngelCartelOfficer,
         const.groupAsteroidBloodRaidersBattleCruiser,
         const.groupAsteroidBloodRaidersBattleship,
         const.groupAsteroidBloodRaidersCruiser,
         const.groupAsteroidBloodRaidersDestroyer,
         const.groupAsteroidBloodRaidersFrigate,
         const.groupAsteroidBloodRaidersHauler,
         const.groupAsteroidBloodRaidersOfficer,
         const.groupAsteroidGuristasBattleCruiser,
         const.groupAsteroidGuristasBattleship,
         const.groupAsteroidGuristasCruiser,
         const.groupAsteroidGuristasDestroyer,
         const.groupAsteroidGuristasFrigate,
         const.groupAsteroidGuristasHauler,
         const.groupAsteroidGuristasOfficer,
         const.groupAsteroidSanshasNationBattleCruiser,
         const.groupAsteroidSanshasNationBattleship,
         const.groupAsteroidSanshasNationCruiser,
         const.groupAsteroidSanshasNationDestroyer,
         const.groupAsteroidSanshasNationFrigate,
         const.groupAsteroidSanshasNationHauler,
         const.groupAsteroidSanshasNationOfficer,
         const.groupAsteroidSerpentisBattleCruiser,
         const.groupAsteroidSerpentisBattleship,
         const.groupAsteroidSerpentisCruiser,
         const.groupAsteroidSerpentisDestroyer,
         const.groupAsteroidSerpentisFrigate,
         const.groupAsteroidSerpentisHauler,
         const.groupAsteroidSerpentisOfficer,
         const.groupDeadspaceAngelCartelBattleCruiser,
         const.groupDeadspaceAngelCartelBattleship,
         const.groupDeadspaceAngelCartelCruiser,
         const.groupDeadspaceAngelCartelDestroyer,
         const.groupDeadspaceAngelCartelFrigate,
         const.groupDeadspaceBloodRaidersBattleCruiser,
         const.groupDeadspaceBloodRaidersBattleship,
         const.groupDeadspaceBloodRaidersCruiser,
         const.groupDeadspaceBloodRaidersDestroyer,
         const.groupDeadspaceBloodRaidersFrigate,
         const.groupDeadspaceGuristasBattleCruiser,
         const.groupDeadspaceGuristasBattleship,
         const.groupDeadspaceGuristasCruiser,
         const.groupDeadspaceGuristasDestroyer,
         const.groupDeadspaceGuristasFrigate,
         const.groupDeadspaceSanshasNationBattleCruiser,
         const.groupDeadspaceSanshasNationBattleship,
         const.groupDeadspaceSanshasNationCruiser,
         const.groupDeadspaceSanshasNationDestroyer,
         const.groupDeadspaceSanshasNationFrigate,
         const.groupDeadspaceSerpentisBattleCruiser,
         const.groupDeadspaceSerpentisBattleship,
         const.groupDeadspaceSerpentisCruiser,
         const.groupDeadspaceSerpentisDestroyer,
         const.groupDeadspaceSerpentisFrigate,
         const.groupDeadspaceSleeperSleeplessPatroller,
         const.groupDeadspaceSleeperSleeplessSentinel,
         const.groupDeadspaceSleeperSleeplessDefender,
         const.groupDeadspaceSleeperAwakenedPatroller,
         const.groupDeadspaceSleeperAwakenedSentinel,
         const.groupDeadspaceSleeperAwakenedDefender,
         const.groupDeadspaceSleeperEmergentPatroller,
         const.groupDeadspaceSleeperEmergentSentinel,
         const.groupDeadspaceSleeperEmergentDefender,
         const.groupDeadspaceOverseer,
         const.groupMissionAmarrEmpireBattlecruiser,
         const.groupMissionAmarrEmpireBattleship,
         const.groupMissionAmarrEmpireCruiser,
         const.groupMissionAmarrEmpireDestroyer,
         const.groupMissionAmarrEmpireFrigate,
         const.groupMissionAmarrEmpireOther,
         const.groupMissionCONCORDBattlecruiser,
         const.groupMissionCONCORDBattleship,
         const.groupMissionCONCORDCruiser,
         const.groupMissionCONCORDDestroyer,
         const.groupMissionCONCORDFrigate,
         const.groupMissionCONCORDOther,
         const.groupMissionCaldariStateBattlecruiser,
         const.groupMissionCaldariStateBattleship,
         const.groupMissionCaldariStateCruiser,
         const.groupMissionCaldariStateDestroyer,
         const.groupMissionCaldariStateFrigate,
         const.groupMissionCaldariStateOther,
         const.groupMissionGallenteFederationBattlecruiser,
         const.groupMissionGallenteFederationBattleship,
         const.groupMissionGallenteFederationCruiser,
         const.groupMissionGallenteFederationDestroyer,
         const.groupMissionGallenteFederationFrigate,
         const.groupMissionGallenteFederationOther,
         const.groupMissionKhanidBattlecruiser,
         const.groupMissionKhanidBattleship,
         const.groupMissionKhanidCruiser,
         const.groupMissionKhanidDestroyer,
         const.groupMissionKhanidFrigate,
         const.groupMissionKhanidOther,
         const.groupMissionMinmatarRepublicBattlecruiser,
         const.groupMissionMinmatarRepublicBattleship,
         const.groupMissionMinmatarRepublicCruiser,
         const.groupMissionMinmatarRepublicDestroyer,
         const.groupMissionMinmatarRepublicFrigate,
         const.groupMissionMinmatarRepublicOther,
         const.groupMissionMorduBattlecruiser,
         const.groupMissionMorduBattleship,
         const.groupMissionMorduCruiser,
         const.groupMissionMorduDestroyer,
         const.groupMissionMorduFrigate,
         const.groupMissionMorduOther,
         const.groupAsteroidAngelCartelCommanderBattleCruiser,
         const.groupAsteroidAngelCartelCommanderCruiser,
         const.groupAsteroidAngelCartelCommanderDestroyer,
         const.groupAsteroidAngelCartelCommanderFrigate,
         const.groupAsteroidBloodRaidersCommanderBattleCruiser,
         const.groupAsteroidBloodRaidersCommanderCruiser,
         const.groupAsteroidBloodRaidersCommanderDestroyer,
         const.groupAsteroidBloodRaidersCommanderFrigate,
         const.groupAsteroidGuristasCommanderBattleCruiser,
         const.groupAsteroidGuristasCommanderCruiser,
         const.groupAsteroidGuristasCommanderDestroyer,
         const.groupAsteroidGuristasCommanderFrigate,
         const.groupAsteroidRogueDroneBattleCruiser,
         const.groupAsteroidRogueDroneBattleship,
         const.groupAsteroidRogueDroneCruiser,
         const.groupAsteroidRogueDroneDestroyer,
         const.groupAsteroidRogueDroneFrigate,
         const.groupAsteroidRogueDroneHauler,
         const.groupAsteroidRogueDroneSwarm,
         const.groupAsteroidSanshasNationCommanderBattleCruiser,
         const.groupAsteroidSanshasNationCommanderCruiser,
         const.groupAsteroidSanshasNationCommanderDestroyer,
         const.groupAsteroidSanshasNationCommanderFrigate,
         const.groupAsteroidSerpentisCommanderBattleCruiser,
         const.groupAsteroidSerpentisCommanderCruiser,
         const.groupAsteroidSerpentisCommanderDestroyer,
         const.groupAsteroidSerpentisCommanderFrigate,
         const.groupDeadspaceRogueDroneBattleCruiser,
         const.groupDeadspaceRogueDroneBattleship,
         const.groupDeadspaceRogueDroneCruiser,
         const.groupDeadspaceRogueDroneDestroyer,
         const.groupDeadspaceRogueDroneFrigate,
         const.groupDeadspaceRogueDroneSwarm,
         const.groupDeadspaceOverseerFrigate,
         const.groupDeadspaceOverseerCruiser,
         const.groupDeadspaceOverseerBattleship,
         const.groupMissionGenericBattleships,
         const.groupMissionGenericCruisers,
         const.groupMissionGenericFrigates,
         const.groupMissionThukkerBattlecruiser,
         const.groupMissionThukkerBattleship,
         const.groupMissionThukkerCruiser,
         const.groupMissionThukkerDestroyer,
         const.groupMissionThukkerFrigate,
         const.groupMissionThukkerOther,
         const.groupMissionGenericBattleCruisers,
         const.groupMissionGenericDestroyers,
         const.groupAsteroidRogueDroneCommanderFrigate,
         const.groupAsteroidRogueDroneCommanderDestroyer,
         const.groupAsteroidRogueDroneCommanderCruiser,
         const.groupAsteroidRogueDroneCommanderBattleCruiser,
         const.groupAsteroidRogueDroneCommanderBattleship,
         const.groupAsteroidAngelCartelCommanderBattleship,
         const.groupAsteroidBloodRaidersCommanderBattleship,
         const.groupAsteroidGuristasCommanderBattleship,
         const.groupAsteroidSanshasNationCommanderBattleship,
         const.groupAsteroidSerpentisCommanderBattleship,
         const.groupMissionAmarrEmpireCarrier,
         const.groupMissionCaldariStateCarrier,
         const.groupMissionGallenteFederationCarrier,
         const.groupMissionMinmatarRepublicCarrier,
         const.groupMissionFighterDrone,
         const.groupMissionGenericFreighters,
         const.groupTutorialDrone,
         const.groupMissionFactionBattleships,
         const.groupMissionFactionCruisers,
         const.groupMissionFactionFrigates,
         const.groupMissionFactionIndustrials,
         const.groupInvasionSanshaNationBattleship,
         const.groupInvasionSanshaNationCapital,
         const.groupInvasionSanshaNationCruiser,
         const.groupInvasionSanshaNationFrigate,
         const.groupInvasionSanshaNationIndustrial]
        self.npcSpecialIcons = [uix.GetTextureTranslation('38_21', 16),
         uix.GetTextureTranslation('38_22', 16),
         uix.GetTextureTranslation('38_23', 16)]
        inf = 1e+32
        self.cat_mapping = {const.categoryShip: ('38_05',
                              1,
                              2000.0,
                              inf,
                              0,
                              0),
         const.categoryEntity: ('38_05',
                                1,
                                0.0,
                                inf,
                                0,
                                0),
         const.categoryDrone: ('38_06',
                               1,
                               0.0,
                               inf,
                               0,
                               0),
         const.categoryDeployable: ('38_129',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.categoryStructure: ('38_129',
                                   1,
                                   0.0,
                                   inf,
                                   0,
                                   0),
         const.categorySovereigntyStructure: ('38_129',
                                              1,
                                              0.0,
                                              inf,
                                              0,
                                              0),
         const.categoryAsteroid: ('38_32',
                                  1,
                                  0.0,
                                  inf,
                                  0,
                                  0),
         const.categoryOrbital: ('38_149',
                                 1,
                                 0.0,
                                 inf,
                                 0,
                                 0)}
        self.grp_mapping = {const.groupCargoContainer: ('38_12',
                                     1,
                                     0.0,
                                     inf,
                                     0,
                                     0),
         const.groupDeadspaceOverseersBelongings: ('38_12',
                                                   1,
                                                   0.0,
                                                   inf,
                                                   0,
                                                   0),
         const.groupFreightContainer: ('38_12',
                                       1,
                                       0.0,
                                       inf,
                                       0,
                                       0),
         const.groupMissionContainer: ('38_12',
                                       1,
                                       0.0,
                                       inf,
                                       0,
                                       0),
         const.groupSecureCargoContainer: ('38_12',
                                           1,
                                           0.0,
                                           inf,
                                           0,
                                           0),
         const.groupAuditLogSecureContainer: ('38_12',
                                              1,
                                              0.0,
                                              inf,
                                              0,
                                              0),
         const.groupSpawnContainer: ('38_12',
                                     1,
                                     0.0,
                                     inf,
                                     0,
                                     0),
         const.groupStation: ('38_252',
                              1,
                              7000.0,
                              inf,
                              0,
                              0),
         const.groupControlBunker: ('38_252',
                                    1,
                                    7000.0,
                                    inf,
                                    0,
                                    0),
         const.groupConstructionPlatform: ('38_252', 1, 7000.0, 50000.0, 0, 0),
         const.groupStationImprovementPlatform: ('38_252', 1, 7000.0, 50000.0, 0, 0),
         const.groupStationUpgradePlatform: ('38_252', 1, 7000.0, 50000.0, 0, 0),
         const.groupDestructibleStationServices: ('38_135',
                                                  1,
                                                  0.0,
                                                  inf,
                                                  0,
                                                  0),
         const.groupStargate: ('38_251',
                               1,
                               0.0,
                               inf,
                               0,
                               0),
         const.groupWarpGate: ('38_250',
                               1,
                               0.0,
                               inf,
                               0,
                               0),
         const.groupAsteroidBelt: ('38_253',
                                   1,
                                   50000.0,
                                   inf,
                                   -20,
                                   0),
         const.groupWreck: ('38_29',
                            1,
                            0.0,
                            inf,
                            0,
                            0),
         const.groupSentryGun: ('38_13',
                                1,
                                2000.0,
                                inf,
                                0,
                                0),
         const.groupMobileSentryGun: ('38_13',
                                      1,
                                      2000.0,
                                      inf,
                                      0,
                                      0),
         const.groupProtectiveSentryGun: ('38_13',
                                          1,
                                          2000.0,
                                          inf,
                                          0,
                                          0),
         const.groupDestructibleSentryGun: ('38_13',
                                            1,
                                            2000.0,
                                            inf,
                                            0,
                                            0),
         const.groupDeadspaceOverseersSentry: ('38_13',
                                               1,
                                               2000.0,
                                               inf,
                                               0,
                                               0),
         const.groupCapsule: ('38_11',
                              1,
                              0.0,
                              inf,
                              0,
                              0),
         const.groupRookieship: ('38_01',
                                 1,
                                 0.0,
                                 inf,
                                 0,
                                 0),
         const.groupFrigate: ('38_01',
                              1,
                              0.0,
                              inf,
                              0,
                              0),
         const.groupShuttle: ('38_01',
                              1,
                              0.0,
                              inf,
                              0,
                              0),
         const.groupAssaultShip: ('38_01',
                                  1,
                                  0.0,
                                  inf,
                                  0,
                                  0),
         const.groupCovertOps: ('38_01',
                                1,
                                0.0,
                                inf,
                                0,
                                0),
         const.groupInterceptor: ('38_01',
                                  1,
                                  0.0,
                                  inf,
                                  0,
                                  0),
         const.groupStealthBomber: ('38_01',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupElectronicAttackShips: ('38_01',
                                            1,
                                            0.0,
                                            inf,
                                            0,
                                            0),
         const.groupPrototypeExplorationShip: ('38_01',
                                               1,
                                               0.0,
                                               inf,
                                               0,
                                               0),
         const.groupDestroyer: ('38_02',
                                1,
                                0.0,
                                inf,
                                0,
                                0),
         const.groupCruiser: ('38_02',
                              1,
                              0.0,
                              inf,
                              0,
                              0),
         const.groupStrategicCruiser: ('38_02',
                                       1,
                                       0.0,
                                       inf,
                                       0,
                                       0),
         const.groupBattlecruiser: ('38_02',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupInterdictor: ('38_02',
                                  1,
                                  0.0,
                                  inf,
                                  0,
                                  0),
         const.groupHeavyAssaultShip: ('38_02',
                                       1,
                                       0.0,
                                       inf,
                                       0,
                                       0),
         const.groupLogistics: ('38_02',
                                1,
                                0.0,
                                inf,
                                0,
                                0),
         const.groupForceReconShip: ('38_02',
                                     1,
                                     0.0,
                                     inf,
                                     0,
                                     0),
         const.groupCombatReconShip: ('38_02',
                                      1,
                                      0.0,
                                      inf,
                                      0,
                                      0),
         const.groupCommandShip: ('38_02',
                                  1,
                                  0.0,
                                  inf,
                                  0,
                                  0),
         const.groupHeavyInterdictors: ('38_02',
                                        1,
                                        0.0,
                                        inf,
                                        0,
                                        0),
         const.groupMiningBarge: ('38_03',
                                  1,
                                  0.0,
                                  inf,
                                  0,
                                  0),
         const.groupIndustrial: ('38_03',
                                 1,
                                 0.0,
                                 inf,
                                 0,
                                 0),
         const.groupIndustrialCommandShip: ('38_03',
                                            1,
                                            0.0,
                                            inf,
                                            0,
                                            0),
         const.groupFreighter: ('38_03',
                                1,
                                0.0,
                                inf,
                                0,
                                0),
         const.groupExhumer: ('38_03',
                              1,
                              0.0,
                              inf,
                              0,
                              0),
         const.groupTransportShip: ('38_03',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupJumpFreighter: ('38_03',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupBattleship: ('38_04',
                                 1,
                                 0.0,
                                 inf,
                                 0,
                                 0),
         const.groupDreadnought: ('38_04',
                                  1,
                                  0.0,
                                  inf,
                                  0,
                                  0),
         const.groupCarrier: ('38_04',
                              1,
                              0.0,
                              inf,
                              0,
                              0),
         const.groupSupercarrier: ('38_04',
                                   1,
                                   0.0,
                                   inf,
                                   0,
                                   0),
         const.groupTitan: ('38_04',
                            1,
                            0.0,
                            inf,
                            0,
                            0),
         const.groupEliteBattleship: ('38_04',
                                      1,
                                      0.0,
                                      inf,
                                      0,
                                      0),
         const.groupCapitalIndustrialShip: ('38_04',
                                            1,
                                            0.0,
                                            inf,
                                            0,
                                            0),
         const.groupMarauders: ('38_04',
                                1,
                                0.0,
                                inf,
                                0,
                                0),
         const.groupBlackOps: ('38_04',
                               1,
                               0.0,
                               inf,
                               0,
                               0),
         const.groupMissile: ('38_07', 1, 0.0, 1.0, 0, 0),
         const.groupBomb: ('38_07',
                           1,
                           0.0,
                           inf,
                           0,
                           0),
         const.groupBeacon: ('38_14',
                             1,
                             0.0,
                             inf,
                             0,
                             0),
         const.groupPlanet: ('38_255',
                             1,
                             0.0,
                             inf,
                             0,
                             0),
         const.groupMoon: ('38_256',
                           0,
                           0.0,
                           inf,
                           0,
                           0),
         const.groupSun: ('38_254',
                          1,
                          0.0,
                          inf,
                          0,
                          0),
         const.groupSecondarySun: ('38_254', 1, 0.0, 1.0, 0, 0),
         const.groupBillboard: ('38_32',
                                1,
                                0.0,
                                inf,
                                0,
                                0),
         const.groupMobileWarpDisruptor: ('38_130',
                                          1,
                                          0.0,
                                          inf,
                                          0,
                                          0),
         const.groupLargeCollidableStructure: ('38_131', 1, 0.0, 250000.0, 0, 0),
         const.groupDeadspaceOverseersStructure: ('38_131', 1, 0.0, 250000.0, 0, 0),
         const.groupControlTower: ('38_132',
                                   1,
                                   0.0,
                                   inf,
                                   0,
                                   0),
         const.groupMoonMining: ('38_133',
                                 1,
                                 0.0,
                                 inf,
                                 0,
                                 0),
         const.groupMobileShieldGenerator: ('38_134',
                                            1,
                                            0.0,
                                            inf,
                                            0,
                                            0),
         const.groupAssemblyArray: ('38_135',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupMobileLaboratory: ('38_135',
                                       1,
                                       0.0,
                                       inf,
                                       0,
                                       0),
         const.groupCorporateHangarArray: ('38_136',
                                           1,
                                           0.0,
                                           inf,
                                           0,
                                           0),
         const.groupMobileReactor: ('38_137',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupRefiningArray: ('38_137',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupMobileMissileSentry: ('38_138',
                                          1,
                                          0.0,
                                          inf,
                                          0,
                                          0),
         const.groupMobileHybridSentry: ('38_13',
                                         1,
                                         0.0,
                                         inf,
                                         0,
                                         0),
         const.groupMobileLaserSentry: ('38_13',
                                        1,
                                        0.0,
                                        inf,
                                        0,
                                        0),
         const.groupMobileProjectileSentry: ('38_13',
                                             1,
                                             0.0,
                                             inf,
                                             0,
                                             0),
         const.groupEnergyNeutralizingBattery: ('38_238',
                                                1,
                                                0.0,
                                                inf,
                                                0,
                                                0),
         const.groupCynosuralGeneratorArray: ('38_237',
                                              1,
                                              0.0,
                                              inf,
                                              0,
                                              0),
         const.groupCynosuralSystemJammer: ('38_239',
                                            1,
                                            0.0,
                                            inf,
                                            0,
                                            0),
         const.groupJumpPortalArray: ('38_236',
                                      1,
                                      0.0,
                                      inf,
                                      0,
                                      0),
         const.groupScannerArray: ('38_240',
                                   1,
                                   0.0,
                                   inf,
                                   0,
                                   0),
         const.groupMobilePowerCore: ('38_139',
                                      1,
                                      0.0,
                                      inf,
                                      0,
                                      0),
         const.groupMobileStorage: ('38_148',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupElectronicWarfareBattery: ('38_149',
                                               1,
                                               0.0,
                                               inf,
                                               0,
                                               0),
         const.groupSensorDampeningBattery: ('38_149',
                                             1,
                                             0.0,
                                             inf,
                                             0,
                                             0),
         const.groupStasisWebificationBattery: ('38_149',
                                                1,
                                                0.0,
                                                inf,
                                                0,
                                                0),
         const.groupWarpScramblingBattery: ('38_149',
                                            1,
                                            0.0,
                                            inf,
                                            0,
                                            0),
         const.groupWarpScramblingBattery: ('38_149',
                                            1,
                                            0.0,
                                            inf,
                                            0,
                                            0),
         const.groupShieldHardeningArray: ('38_149',
                                           1,
                                           0.0,
                                           inf,
                                           0,
                                           0),
         const.groupTrackingArray: ('38_149',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupStealthEmitterArray: ('38_149',
                                          1,
                                          0.0,
                                          inf,
                                          0,
                                          0),
         const.groupAgentsinSpace: ('38_37',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupDestructibleAgentsInSpace: ('38_37',
                                                1,
                                                0.0,
                                                inf,
                                                0,
                                                0),
         const.groupHarvestableCloud: ('38_32',
                                       1,
                                       50000.0,
                                       inf,
                                       -20,
                                       0),
         const.groupScannerProbe: ('38_120',
                                   1,
                                   0.0,
                                   inf,
                                   -20,
                                   0),
         const.groupCapturePointTower: ('38_130',
                                        1,
                                        0.0,
                                        inf,
                                        -20,
                                        0),
         const.groupControlBunker: ('38_164',
                                    1,
                                    0.0,
                                    inf,
                                    0,
                                    0),
         const.groupWormhole: ('38_235',
                               1,
                               0.0,
                               inf,
                               0,
                               0),
         const.groupPlanetaryCustomsOffices: ('38_31',
                                              1,
                                              0.0,
                                              inf,
                                              0,
                                              0),
         const.groupFlashpoint: ('38_164',
                                 1,
                                 0.0,
                                 inf,
                                 0,
                                 0),
         const.groupImpactor: ('38_07', 1, 0.0, 60000.0, 0, 0)}
        for group in cfg.invgroups:
            if (group.fittableNonSingleton and (not self.grp_mapping.has_key(group.groupID))):
                self.grp_mapping[group.groupID] = self.grp_mapping[const.groupMissile]

        for bombGroup in [const.groupBomb,
         const.groupBombECM,
         const.groupBombEnergy]:
            self.grp_mapping[bombGroup] = self.grp_mapping[const.groupBomb]

        self.type_mapping = {const.typeBeacon: ('38_14',
                            1,
                            150000.0,
                            inf,
                            0,
                            0),
         const.typeCelestialBeaconII: ('38_30',
                                       1,
                                       150000.0,
                                       inf,
                                       0,
                                       0),
         const.typeCelestialAgentSiteBeacon: ('38_46',
                                              1,
                                              150000.0,
                                              inf,
                                              0,
                                              0),
         const.typeThePrizeContainer: ('38_12',
                                       1,
                                       0.0,
                                       inf,
                                       0,
                                       0)}
        for set in (self.cat_mapping,
         self.grp_mapping,
         self.type_mapping):
            for (key, (iconNum, dockType, minDist, maxDist, iconOffset, logflag,),) in set.iteritems():
                (iconX, iconY,) = uix.GetTextureTranslation(iconNum, 16)
                set[key] = (iconX,
                 iconY,
                 dockType,
                 minDist,
                 maxDist,
                 iconOffset,
                 logflag)





    def ShowAll(self):
        if (self.showState != SHOW_ALL):
            self.showState = SHOW_ALL
            bp = sm.StartService('michelle').GetBallpark(doWait=True)
            if (bp is None):
                return 
            lst = []
            for (ballID, ball,) in bp.balls.iteritems():
                if ((ballID < 0) or (ballID in self.brackets.keys())):
                    continue
                slimItem = bp.GetInvItem(ballID)
                if slimItem:
                    lst.append((ball, slimItem))

            self.DoBallsAdded(lst, useFilter=False)
        self.UpdateOverviewSettings()



    def UpdateOverviewSettings(self):
        overview = sm.StartService('tactical').GetPanelForUpdate('overview')
        if overview:
            selectedTabKey = overview.GetSelectedTabKey()
            tabsettings = settings.user.overview.Get('tabsettings', {})
            tabsetting = tabsettings.get(selectedTabKey, None)
            if tabsetting:
                tabsetting['showAll'] = (self.showState == SHOW_ALL)
                tabsetting['showNone'] = (self.showState == SHOW_NONE)



    def ShowNone(self):
        if (self.showState != SHOW_NONE):
            self.showState = SHOW_NONE
            bp = sm.StartService('michelle').GetBallpark(doWait=True)
            if (bp is None):
                return 
            lst = []
            for (ballID, ball,) in bp.balls.iteritems():
                if (ballID is None):
                    log.LogTraceback('bracketMgr::ShowNone - ballID is None!!!')
                    continue
                if (ballID < 0):
                    continue
                if self.IsWanted(ballID):
                    continue
                lst.append(ballID)
                continue

            self.ClearBrackets(lst)
        self.UpdateOverviewSettings()



    def ShowAllHidden(self):
        if not self.showHiddenTimer:
            if self.brackets.has_key(session.shipid):
                self.brackets[session.shipid].ShowTempIcon()
            self.showHiddenTimer = base.AutoTimer(100, self.StopShowingHidden)



    def ToggleShowSpecials(self):
        if not getattr(self, 'showingSpecials', False):
            self.DoToggleShowSpecials(True)
        else:
            self.DoToggleShowSpecials(False)



    def DoToggleShowSpecials(self, isShow):
        if isShow:
            self.showingSpecials = True
            bp = sm.GetService('michelle').GetBallpark()
            lst = []
            if not bp:
                return 
            for (ballID, ball,) in bp.balls.iteritems():
                if (ballID in self.brackets.keys()):
                    continue
                slimItem = bp.GetInvItem(ballID)
                if (slimItem and (slimItem.groupID in self.specials)):
                    lst.append((ball, slimItem))

            self.DoBallsAdded(lst)
        else:
            self.showingSpecials = False
            lst = []
            for (ballID, ball,) in self.brackets.iteritems():
                if ((getattr(ball, 'groupID', None) in self.specials) and (not self.IsSelectedOrTargeted(ballID))):
                    lst.append(ballID)

            self.ClearBrackets(lst)
        overview = sm.StartService('tactical').GetPanelForUpdate('overview')
        if overview:
            selectedTabKey = overview.GetSelectedTabKey()
            tabsettings = settings.user.overview.Get('tabsettings', {})
            tabsetting = tabsettings.get(selectedTabKey, None)
            if tabsetting:
                tabsetting['showSpecials'] = self.showingSpecials



    def ShowingAll(self):
        return (self.showState == SHOW_ALL)



    def ShowingNone(self):
        return (self.showState == SHOW_NONE)



    def ShowingHidden(self):
        return (not (not self.showHiddenTimer))



    def StopShowingAllNone(self):
        self.showState = SHOW_DEFAULT
        lst = []
        for (ballID, ball,) in self.brackets.iteritems():
            if ((not self.IsWanted(ballID)) and ball):
                lst.append(ballID)

        self.ClearBrackets(lst)
        self.UpdateOverviewSettings()



    def StopShowingAll(self):
        self.showState = SHOW_DEFAULT
        lst = []
        for (ballID, ball,) in self.brackets.iteritems():
            if ((not self.IsWanted(ballID)) and ball):
                lst.append(ballID)

        self.ClearBrackets(lst)
        self.UpdateOverviewSettings()



    def StopShowingNone(self):
        self.showState = SHOW_DEFAULT
        lst = []
        for (ballID, ball,) in self.brackets.iteritems():
            if ((not self.IsWanted(ballID)) and ball):
                lst.append(ballID)

        self.ClearBrackets(lst)
        self.UpdateOverviewSettings()
        bp = sm.StartService('michelle').GetBallpark(doWait=True)
        if (bp is None):
            return 
        lst = []
        for (ballID, ball,) in bp.balls.iteritems():
            if ((ballID < 0) or ((ballID in self.brackets.keys()) or (ball is None))):
                continue
            if self.IsWanted(ballID):
                slimItem = bp.GetInvItem(ballID)
                if slimItem:
                    lst.append((ball, slimItem))

        self.DoBallsAdded(lst, useFilter=False)
        self.UpdateOverviewSettings()



    def StopShowingHidden(self):
        alt = eve.triapp.uilib.Key(uix.VK_MENU)
        if not alt:
            self.showHiddenTimer = None
            if self.brackets.has_key(session.shipid):
                self.brackets[session.shipid].HideTempIcon()



    def ClearBrackets(self, lst):
        for ballID in lst:
            self.ClearBracket(ballID)




    def IsWanted(self, ballID, ignoreState = False):
        slimItem = sm.StartService('michelle').GetBallpark().GetInvItem(ballID)
        if (slimItem is None):
            uix.LogWarn('IsWanted - ball', ballID, 'not found in park')
            return False
        if (slimItem.groupID in self.unwantedBracketGroups):
            return False
        filtered = sm.GetService('tactical').GetFilteredStatesFunctionNames(isBracket=True)
        wanted = False
        isSpecial = (slimItem.groupID in self.specials)
        if (isSpecial and getattr(self, 'showingSpecials', False)):
            return True
        if not isSpecial:
            if (self.showState == SHOW_ALL):
                return True
            if ((self.showState == SHOW_NONE) and (not self.IsSelectedOrTargeted(ballID))):
                return False
            if isSpecial:
                return (self.IsSelectedOrTargeted(ballID) and (not ignoreState))
            return (sm.StartService('tactical').WantIt(slimItem, filtered, isBracket=True) or (self.IsSelectedOrTargeted(ballID) and (not ignoreState)))



    def IsSelectedOrTargeted(self, ballID):
        stateMgr = sm.GetService('state')
        for isWanted in stateMgr.GetStates(ballID, [state.selected,
         state.targeted,
         state.targeting,
         state.activeTarget]):
            if isWanted:
                return True

        return sm.StartService('target').IsTarget(ballID)



    def GetBracketName(self, objectID):
        if (objectID in self.brackets):
            return self.brackets[objectID].displayName
        else:
            return ''



    def GetBracketName2(self, objectID):
        ret = self.GetBracketName(objectID)
        if (ret != ''):
            return ret
        else:
            slimItem = sm.GetService('michelle').GetBallpark().slimItems.get(objectID, None)
            if not objectID:
                return ''
            return self.DisplayName(slimItem, uix.GetSlimItemName(slimItem))



    def SetBracketName(self, objectID, newName):
        if (objectID in self.brackets):
            self.brackets[objectID].displayName = newName



    def DisplayName(self, slimItem, displayName):
        shiplabel = []
        if not getattr(self, 'shipLabels', None):
            self.shipLabels = sm.GetService('state').GetShipLabels()
            self.hideCorpTicker = sm.GetService('state').GetHideCorpTicker()
        for label in self.shipLabels:
            if label['state']:
                (type, pre, post,) = (label['type'], label['pre'], label['post'])
                if ((type is None) and (slimItem.corpID and (not util.IsNPC(slimItem.corpID)))):
                    shiplabel.append(pre)
                if ((type == 'corporation') and (slimItem.corpID and ((not util.IsNPC(slimItem.corpID)) and (not (self.hideCorpTicker and slimItem.allianceID))))):
                    shiplabel += [pre,
                     cfg.corptickernames.Get(slimItem.corpID).tickerName,
                     post]
                if ((type == 'alliance') and slimItem.allianceID):
                    try:
                        shiplabel += [pre,
                         cfg.allianceshortnames.Get(slimItem.allianceID).shortName,
                         post]
                    except:
                        uix.LogError('Failed to get allianceName, itemID:', slimItem.itemID, 'allianceID:', slimItem.allianceID)
                if (type == 'pilot name'):
                    shiplabel += [pre,
                     displayName,
                     post]
                if (type == 'ship type'):
                    shiplabel += [pre,
                     cfg.invtypes.Get(slimItem.typeID).name,
                     post]
                if (type == 'ship name'):
                    name = cfg.evelocations.Get(slimItem.itemID).name
                    if name:
                        shiplabel += [pre,
                         name,
                         post]

        return ''.join(shiplabel)



    def OnSlimItemChange(self, oldSlim, newSlim):
        if util.IsStructure(newSlim.categoryID):
            if ((newSlim.posState == oldSlim.posState) and ((newSlim.posTimestamp == oldSlim.posTimestamp) and ((newSlim.incapacitated == oldSlim.incapacitated) and ((newSlim.controllerID == oldSlim.controllerID) and (newSlim.ownerID == oldSlim.ownerID))))):
                return 
            bracket = self.brackets.get(newSlim.itemID, None)
            if bracket:
                bracket.wr.slimItem = newSlim
                bracket.displayName = self.DisplayName(newSlim, uix.GetSlimItemName(newSlim))
                bracket.UpdateStructureState(newSlim)
        elif util.IsOrbital(newSlim.categoryID):
            if ((newSlim.orbitalState == oldSlim.orbitalState) and ((newSlim.orbitalTimestamp == oldSlim.orbitalTimestamp) and (newSlim.ownerID == oldSlim.ownerID))):
                return 
            bracket = self.brackets.get(newSlim.itemID, None)
            if (bracket is not None):
                bracket.wr.slimItem = newSlim
                bracket.displayName = self.DisplayName(newSlim, uix.GetSlimItemName(newSlim))
                bracket.UpdateOrbitalState(newSlim)
        elif ((newSlim.categoryID == const.categoryShip) and (newSlim.itemID in self.brackets)):
            self.brackets[newSlim.itemID].wr.slimItem = newSlim
            self.brackets[newSlim.itemID].displayName = self.DisplayName(newSlim, uix.GetSlimItemName(newSlim))
        elif (newSlim.categoryID == const.categoryStation):
            bracket = self.brackets.get(newSlim.itemID, None)
            if bracket:
                bracket.wr.slimItem = newSlim
                bracket.displayName = self.DisplayName(newSlim, uix.GetSlimItemName(newSlim))
                bracket.UpdateOutpostState(newSlim, oldSlim)
        elif (newSlim.itemID in self.brackets):
            self.brackets[newSlim.itemID].wr.slimItem = newSlim
        if (newSlim.corpID != oldSlim.corpID):
            if (newSlim.itemID in self.brackets):
                bracket = self.brackets[newSlim.itemID]
                uthread.pool('BracketMgr::OnSlimItemChange --> UpdateStates', sm.GetService('tactical').UpdateStates, newSlim, bracket)
        if ((newSlim.groupID == const.groupWreck) and (newSlim.isEmpty and (not oldSlim.isEmpty))):
            sm.GetService('state').SetState(newSlim.itemID, state.flagWreckEmpty, True)
        if (newSlim.groupID in [const.groupWreck, const.groupCargoContainer]):
            self.RenewBracket(newSlim)



    def ProcessSessionChange(self, isremote, session, change):
        if ((not sm.GetService('connection').IsConnected()) or ((session.stationid is not None) or ((session.worldspaceid is not None) or (session.charid is None)))):
            self.CleanUp()
        elif ((not change.has_key('solarsystemid')) and (change.has_key('shipid') and (change['shipid'][0] is not None))):
            (oldShipID, shipID,) = change['shipid']
            bp = sm.GetService('michelle').GetBallpark()
            (ball, slimItem,) = (bp.GetBall(oldShipID), bp.GetInvItem(oldShipID))
            if ((ball is not None) and (slimItem is not None)):
                self.DoBallsAdded([(ball, slimItem)])
            (ball, slimItem,) = (bp.GetBall(shipID), bp.GetInvItem(shipID))
            if ((ball is not None) and (slimItem is not None)):
                self.DoBallsAdded([(ball, slimItem)])



    def GetBracketProps(self, slimItem, ball):
        if not self.gotProps:
            self.gotProps = 1
            self.SetupProps()
        if ((slimItem.groupID in self.npcSpecial) and (ball is not None)):
            if (ball.radius <= 85):
                size = 0
            elif 85 < ball.radius <= 240:
                size = 1
            else:
                size = 2
            icon = self.npcSpecialIcons[size]
            return (icon[0],
             icon[1],
             1,
             0.0,
             1e+32,
             0,
             0)
        else:
            return self.GetMappedBracketProps(slimItem.categoryID, slimItem.groupID, slimItem.typeID)



    def GetMappedBracketProps(self, categoryID, groupID, typeID, default = None):
        props = (default or (0.0, 0.9375, 0, 0.0, 1e+32, 0, 1))
        if (typeID in self.type_mapping):
            props = self.type_mapping[typeID]
        elif (groupID in self.grp_mapping):
            props = self.grp_mapping[groupID]
        elif (categoryID in self.cat_mapping):
            props = self.cat_mapping[categoryID]
        return props



    def SlimItemIsDungeonObjectWithTriggers(self, slimItem):
        if (self.scenarioMgr.editDungeonID and ('/jessica' in blue.pyos.GetArg())):
            import dungeon
            objectID = slimItem.dunObjectID
            if objectID:
                obj = dungeon.Object.Get(objectID)
                if (obj is not None):
                    return obj.HasAnyTriggers()



    def PrimeLocations(self, slimItem):
        locations = []
        for each in slimItem.jumps:
            if (each.locationID not in locations):
                locations.append(each.locationID)
            if (each.toCelestialID not in locations):
                locations.append(each.toCelestialID)

        if len(locations):
            cfg.evelocations.Prime(locations)



    def AddTempBracket(self, itemID):
        return 



    def DoBallsAdded(self, *args, **kw):
        t = stackless.getcurrent()
        timer = t.PushTimer((blue.pyos.taskletTimer.GetCurrent() + '::BracketMgr'))
        try:
            return self.DoBallsAdded_(*args, **kw)

        finally:
            t.PopTimer(timer)




    def DoBallsAdded_(self, lst, useFilter = True, ignoreMoons = 0, ignoreAsteroids = 1):
        uthread.worker('BracketMgr::UpdateBracketsForDungeonEditing', self.UpdateBracketsForDungeonEditing, lst)
        if not hasattr(self, 'specialGroups'):
            self.specialGroups = (const.groupMoon, const.groupLargeCollidableStructure)
        t = blue.os.GetTime(1)
        if not self.gotProps:
            self.gotProps = 1
            self.SetupProps()
        wnd = uicore.layer.bracket
        ignoreGroup = [const.groupForceField, const.groupCloud]
        ignoreCateg = []
        if ignoreAsteroids:
            ignoreCateg += [const.categoryAsteroid]
            ignoreGroup += [const.groupHarvestableCloud]
        if ignoreMoons:
            ignoreGroup += [const.groupMoon]
        filterLCS = ['wall_x',
         'wall_z',
         ' wall',
         ' barricade',
         ' fence',
         ' barrier',
         ' junction',
         ' elevator',
         ' lookout',
         ' neon sign']
        currNumNPC = 1
        currNumAsteroidBelt = 1
        currNumAsteroid = 1
        currNumStations = 1
        for (ball, slimItem,) in lst:
            show = 1
            if (slimItem.groupID == const.groupDeadspaceOverseersStructure):
                checkName = cfg.invtypes.Get(slimItem.typeID).name.lower()
                for each in filterLCS:
                    if (each in checkName):
                        show = 0
                        break

            if ((not show) or ((slimItem.groupID in ignoreGroup) or (slimItem.categoryID in ignoreCateg))):
                continue
            if not self.IsWanted(ball.id):
                continue
            bracket = self.brackets.get(ball.id, None)
            if bracket:
                self.ClearBracket(ball.id, bracket)
            panel = self.GetNewBracket()
            if (hasattr(slimItem, 'typeID') and (slimItem.typeID == const.typeAsteroidBelt)):
                panel.name = ('bracketAsteroidBelt%s' % currNumAsteroidBelt)
                currNumAsteroidBelt += 1
            elif (hasattr(slimItem, 'categoryID') and (slimItem.categoryID == const.categoryAsteroid)):
                panel.name = ('bracketAsteroid%s' % currNumAsteroid)
                currNumAsteroid += 1
            elif (hasattr(slimItem, 'categoryID') and (slimItem.categoryID == const.categoryStation)):
                panel.name = ('bracketStation%s' % currNumStations)
                currNumStations += 1
            else:
                if (hasattr(slimItem, 'ownerID') and hasattr(slimItem, 'groupID')):
                    if ((slimItem.ownerID == const.factionUnknown) and (slimItem.groupID == const.groupPirateDrone)):
                        panel.name = ('bracketNPCPirateDrone%s' % currNumNPC)
                        currNumNPC += 1
            panel.displayName = self.GetDisplayNameForBracket(slimItem)
            if (panel.displayName is None):
                panel.Close()
                continue
            self.SetupBracketProperties(panel, ball, slimItem)
            panel.updateItem = (sm.GetService('state').CheckIfUpdateItem(slimItem) and (ball.id != eve.session.shipid))
            wnd.children.append(panel)
            panel.Startup(slimItem, ball)
            self.brackets[ball.id] = panel
            if panel.updateItem:
                self.updateBrackets.append(ball.id)
            if (hasattr(self, 'capturePoints') and (ball.id in self.capturePoints.keys())):
                self.brackets[ball.id].UpdateCaptureProgress(self.capturePoints[ball.id])




    def GetNewBracket(self):
        return self.bracketTemplate.CopyTo()



    def GetDisplayNameForBracket(self, slimItem):
        try:
            displayName = uix.GetSlimItemName(slimItem)
        except:
            return 
        if (slimItem.groupID in self.grp_mapping.iterkeys()):
            if (slimItem.groupID == const.groupStation):
                displayName = uix.EditStationName(displayName, usename=1)
            elif (slimItem.groupID == const.groupStargate):
                uthread.new(self.PrimeLocations, slimItem)
            elif (slimItem.groupID == const.groupHarvestableCloud):
                displayName = ('%s (%s)' % (mls.UI_GENERIC_HARVESTABLE_CLOUD, cfg.invtypes.Get(slimItem.typeID).name))
            else:
                if (slimItem.categoryID == const.categoryAsteroid):
                    displayName = ('%s (%s)' % (mls.UI_GENERIC_ASTEROID, cfg.invtypes.Get(slimItem.typeID).name))
        if slimItem.corpID:
            displayName = self.DisplayName(slimItem, displayName)
        return displayName



    def UpdateBracketsForDungeonEditing(self, objectList):
        bracketWindow = uicore.layer.bracket
        for (ball, slimItem,) in objectList:
            if not self.SlimItemIsDungeonObjectWithTriggers(slimItem):
                continue
            bracket = self.brackets.get(ball.id, None)
            if bracket:
                self.ClearBracket(ball.id, bracket)
            bracket = self.GetNewBracket()
            bracket.name = ('bracketForTriggerObject%d' % slimItem.dunObjectID)
            bracket.displayName = (self.GetDisplayNameForBracket(slimItem) + ' (Trigger)')
            props = self.GetBracketProps(slimItem, ball)
            props = ((0.625, 0.5) + props[2:])
            self.SetupBracketProperties(bracket, ball, slimItem, props)
            bracket.updateItem = False
            bracketWindow.children.append(bracket)
            bracket.Startup(slimItem, ball)
            self.brackets[ball.id] = bracket




    def SetupBracketProperties(self, bracket, ball, slimItem, props = None):
        if (props is None):
            props = self.GetBracketProps(slimItem, ball)
        (_iconX, _iconY, _dockType, _minDist, _maxDist, _iconOffset, _logflag,) = props
        bracket.data = props
        bracket.trackBall = ball
        bracket.dock = _dockType
        bracket.minDispRange = _minDist
        bracket.maxDispRange = _maxDist
        bracket.inflight = True
        bracket.color = trinity.TriColor()
        bracket.invisible = (ball.id == eve.session.shipid)



    def UpdateLabels(self):
        self.shipLabels = sm.GetService('state').GetShipLabels()
        self.hideCorpTicker = sm.GetService('state').GetHideCorpTicker()
        for bracket in self.brackets:
            slimItem = self.brackets[bracket].wr.slimItem
            if slimItem.corpID:
                self.brackets[slimItem.itemID].displayName = self.DisplayName(slimItem, uix.GetSlimItemName(slimItem))




    def RenewFlags(self):
        uthread.pool('BracketMgr::RenewFlags', self._RenewFlags)



    def _RenewFlags(self):
        for itemID in self.updateBrackets[:]:
            (slimItem, bracket,) = self.GetSlimItem(itemID)
            if (bracket is None):
                continue
            if slimItem:
                bracket.Load_update(slimItem)
            blue.pyos.BeNice()




    def RenewSingleFlag(self, charID):
        uthread.new(self._RenewSingleFlag, charID)



    def _RenewSingleFlag(self, charID):
        bp = sm.GetService('michelle').GetBallpark()
        if not bp:
            return 
        for itemID in self.updateBrackets[:]:
            (slimItem, bracket,) = self.GetSlimItem(itemID)
            if (slimItem is None):
                continue
            slimCharID = getattr(slimItem, 'charID', None)
            if (slimCharID is None):
                continue
            if (slimCharID == charID):
                bracket.Load_update(slimItem)
                return 
            blue.pyos.BeNice()




    def GetSlimItem(self, itemID):
        bracket = self.GetBracket(itemID)
        if not bracket:
            if (itemID in self.updateBrackets):
                self.updateBrackets.remove(itemID)
            return (None, None)
        else:
            slimItem = bracket.wr.slimItem
            return (slimItem, bracket)



    def RenewBracket(self, slimItem):
        if (slimItem is None):
            return 
        bracket = self.GetBracket(slimItem.itemID)
        if (bracket is not None):
            bracket.Load_update(slimItem)



    def OnBallparkCall(self, funcName, args):
        if (funcName == 'SetBallFree'):
            (itemID, isFree,) = args
            bracket = self.GetBracket(itemID)
            if bracket:
                slimItem = bracket.wr.slimItem
                if slimItem:
                    bracket.SetBracketAnchoredState(slimItem)



    def DoBallRemove(self, ball, slimItem, terminal):
        if (ball is None):
            return 
        self.LogInfo('DoBallRemove::bracketMgr', ball.id)
        self.ClearBracket(ball.id)
        if (ball.id in getattr(self, 'capturePoints', {}).keys()):
            del self.capturePoints[ball.id]



    def DoBallClear(self, solitem):
        if not self.brackets:
            return 
        self.brackets = {}
        self.updateBrackets = []
        for bracket in uicore.layer.bracket.children:
            bracket.trackBall = None
            bracket.trackTransform = None
            bracket.Close()




    def OnDestinationSet(self, destinationID = None):
        sg = const.groupStargate
        destinationPath = sm.GetService('starmap').GetDestinationPath()
        for each in uicore.layer.bracket.children[:]:
            if not getattr(each, 'IsBracket', 0):
                continue
            if ((each is None) or (each.destroyed or ((not getattr(each, 'IsBracket', None)) or ((not each.wr.slimItem) or (each.groupID != sg))))):
                continue
            if each.sr.icon:
                slimItem = getattr(each.wr, 'slimItem', None)
                each.sr.icon.color.SetRGB(1.0, 1.0, 1.0)
                if (slimItem.jumps[0].locationID in destinationPath):
                    each.sr.icon.color.SetRGB(1.0, 1.0, 0.0)
                    uiutil.SetOrder(each, 0)




    def OnStateChange(self, itemID, flag, true, *args):
        if (flag in (state.selected,
         state.targeted,
         state.targeting)):
            slimItem = uix.GetBallparkRecord(itemID)
            if (slimItem and ((self.showState == SHOW_NONE) or ((slimItem.categoryID == const.categoryAsteroid) or ((slimItem.groupID == const.groupHarvestableCloud) or (not self.IsWanted(slimItem.itemID, ignoreState=True)))))):
                bracket = self.GetBracket(itemID)
                if (true and (not bracket)):
                    ball = sm.GetService('michelle').GetBall(slimItem.itemID)
                    if ball:
                        self.DoBallsAdded([(ball, slimItem)], useFilter=False, ignoreAsteroids=0)
                elif ((not true) and (bracket and (not sm.GetService('target').IsTarget(itemID)))):
                    self.ClearBracket(slimItem.itemID, bracket)
                    if self.SlimItemIsDungeonObjectWithTriggers(slimItem):
                        ball = sm.GetService('michelle').GetBall(slimItem.itemID)
                        self.UpdateBracketsForDungeonEditing([(ball, slimItem)])
                    return 
        bracket = self.GetBracket(itemID)
        if bracket:
            bracket.OnStateChange(itemID, flag, true, *args)



    def OnAttribute(self, attributeName, item, newValue):
        if ((item.itemID == session.shipid) and (attributeName == 'scanResolution')):
            for targetID in sm.GetService('target').GetTargeting():
                bracket = self.GetBracket(targetID)
                if (bracket and hasattr(bracket, 'OnAttribute')):
                    bracket.OnAttribute(attributeName, item, newValue)




    def OnAttributes(self, changeList):
        for t in changeList:
            self.OnAttribute(*t)




    def OnPostCfgDataChanged(self, what, data):
        if (what == 'evelocations'):
            bracket = self.GetBracket(data[0])
            if ((bracket is not None) and getattr(bracket.wr, 'slimItem', None)):
                bracket.displayName = self.DisplayName(bracket.wr.slimItem, uix.GetSlimItemName(bracket.wr.slimItem))



    def OnCaptureChanged(self, ballID, captureID, lastIncident, points, captureTime, lastCapturing):
        bracket = self.GetBracket(ballID)
        if not hasattr(self, 'capturePoints'):
            self.capturePoints = {}
        self.capturePoints[ballID] = {'captureID': captureID,
         'lastIncident': blue.os.GetTime(),
         'points': points,
         'captureTime': captureTime,
         'lastCapturing': lastCapturing}
        if bracket:
            bracket.UpdateCaptureProgress(self.capturePoints[ballID])



    def ResetOverlaps(self):
        for each in self.overlaps[:]:
            if ((not getattr(each, 'IsBracket', 0)) or ((each is None) or each.destroyed)):
                continue
            if (hasattr(each.sr, 'trackBall') and hasattr(each.sr, 'trackTransform')):
                each.trackBall = each.sr.trackBall
                each.trackTransform = each.sr.trackTransform
                each.KillLabel()
                each.opacity = getattr(each, '_pervious_opacity', 1.0)

        for each in self.overlapsHidden[:]:
            bubble = getattr(each.sr, 'bubble', None)
            if bubble:
                bubble.state = uix.UI_PICKCHILDREN

        self.overlaps = []
        self.overlapsHidden = []



    def GetOverlapOverlap(self, sameX, minY, maxY):
        overlaps = []
        stillLeft = []
        for bracket in sameX:
            if ((bracket.absoluteTop > (minY - 16)) and (bracket.absoluteBottom < (maxY + 16))):
                overlaps.append((bracket.displayName.lower(), bracket))
            else:
                stillLeft.append(bracket)

        return (overlaps, stillLeft)



    def CheckingOverlaps(self):
        return self.checkingOverlaps



    def CheckOverlaps(self, sender, hideRest = 0):
        self.checkingOverlaps = sender.itemID
        self.ResetOverlaps()
        overlaps = []
        excludedC = (const.categoryAsteroid)
        excludedG = (const.groupHarvestableCloud)
        sameX = []

        def GetAbsolute(bracket):
            if getattr(bracket.sr, 'icon', None):
                (l, t, w, h,) = bracket.sr.icon.GetAbsolute()
            else:
                (l, t, w, h,) = bracket.GetAbsolute()
            return uiutil.Bunch(left=l, top=t, width=w, height=h, bottom=(t + h), right=(l + w))


        s = GetAbsolute(sender)
        for bracket in sender.parent.children:
            if not (not getattr(bracket, 'IsBracket', 0)):
                if (bracket.state != uix.UI_PICKCHILDREN):
                    continue
                if (bracket.invisible and (bracket.sr.tempIcon is None)):
                    continue
                if (bracket.categoryID in excludedC):
                    continue
                if (bracket.groupID in excludedG):
                    continue
                if (bracket == sender):
                    pass
            b = GetAbsolute(bracket)
            overlapx = (not ((b.right <= s.left) or (b.left >= s.right)))
            overlapy = (not ((b.bottom <= s.top) or (b.top >= s.bottom)))
            if (overlapx and overlapy):
                overlaps.append((bracket.displayName.lower(), bracket))
            else:
                if (overlapx and (not overlapy)):
                    sameX.append(bracket)

        if not overlaps:
            self.checkingOverlaps = None
            sender.parent.state = uix.UI_PICKCHILDREN
            return 

        def GroupHeight(group):
            return sum([ GetAbsolute(b).height for (name, b,) in group ])


        totalH = GroupHeight(overlaps)
        minY = (sender.absoluteTop - totalH)
        if sameX:
            for i in xrange(10):
                minY = (sender.absoluteTop - totalH)
                maxY = s.bottom
                (oo, sameX,) = self.GetOverlapOverlap(sameX, minY, maxY)
                if not oo:
                    break
                overlaps.extend(oo)
                totalH += GroupHeight(oo)

        overlaps = uiutil.SortListOfTuples(overlaps)
        overlaps.reverse()

        def Nail(bracket, top):
            bracket.sr.trackBall = bracket.trackBall
            bracket.sr.trackTransform = bracket.trackTransform
            bracket.trackBall = None
            bracket.trackTransform = None
            bracket.left = ((s.left + (s.width / 2)) - (bracket.width / 2))
            bracket.top = (top - ((bracket.height - 16) / 2))
            bracket._pervious_opacity = bracket.opacity
            bracket.opacity = 1.0
            if not getattr(bracket.sr, 'bubble', False):
                bracket.ShowLabel()
            uiutil.SetOrder(bracket, 0)


        top = s.top
        Nail(sender, top)
        if getattr(sender.sr, 'hitchhiker', None):
            (lh, th, wh, hh,) = sender.sr.hitchhiker.GetAbsolute()
            top -= hh
        hasBubble = bool(getattr(sender.sr, 'bubble', False))
        if hasBubble:
            if (sender.sr.bubble.data[1] in (0, 1, 2)):
                top -= (sender.sr.bubble.height + 8)
        for bracket in overlaps:
            shift = GetAbsolute(bracket).height
            shift += 2
            hasBubble = bool(getattr(bracket.sr, 'bubble', False))
            if hasBubble:
                if (bracket.sr.bubble.data[1] in (3, 4, 5)):
                    shift += (bracket.sr.bubble.height + 8)
            top -= shift
            Nail(bracket, top)
            if getattr(bracket.sr, 'hitchhiker', None):
                (lh, th, wh, hh,) = bracket.sr.hitchhiker.GetAbsolute()
                top -= hh
            if hasBubble:
                if (bracket.sr.bubble.data[1] in (0, 1, 2)):
                    top -= (bracket.sr.bubble.height + 8)

        self.overlapsHidden = []
        if hideRest:
            for bracket in sender.parent.children:
                if ((bracket is sender) or ((bracket in overlaps) or ((not getattr(bracket, 'IsBracket', 0)) or ((bracket.state != uix.UI_PICKCHILDREN) or (bracket.invisible and (bracket.sr.tempIcon is None)))))):
                    continue
                bubble = getattr(bracket.sr, 'bubble', None)
                if bubble:
                    bubble.state = uix.UI_HIDDEN
                    self.overlapsHidden.append(bracket)

        self.overlaps = ([sender] + overlaps)
        sender.parent.state = uix.UI_PICKCHILDREN
        self.checkingOverlaps = None



    def GetBracket(self, bracketID):
        if (getattr(self, 'brackets', None) is not None):
            return self.brackets.get(bracketID, None)



    def ClearBracket(self, id, bracket = None):
        if getattr(self, 'brackets'):
            bracket = (bracket or self.GetBracket(id))
            if (id in self.brackets):
                del self.brackets[id]
            if (id in self.updateBrackets):
                self.updateBrackets.remove(id)
            if ((bracket is not None) and (not bracket.destroyed)):
                bracket.trackTransform = None
                bracket.trackBall = None
                bracket.Close()



    def GetScanSpeed(self, source = None, target = None):
        if (source is None):
            source = eve.session.shipid
        if not source:
            return 
        else:
            scanAttributeChangeFlag = False
            myitem = sm.GetService('godma').GetItem(source)
            scanSpeed = None
            if (myitem.scanResolution and target):
                slimItem = target
                targetitem = sm.GetService('godma').GetType(slimItem.typeID)
                if targetitem.AttributeExists('signatureRadius'):
                    radius = targetitem.signatureRadius
                else:
                    radius = 0
                if (radius <= 0.0):
                    bp = sm.GetService('michelle').GetBallpark()
                    radius = bp.GetBall(slimItem.itemID).radius
                    if (radius <= 0.0):
                        radius = cfg.invtypes.Get(targetitem.typeID).radius
                        if (radius <= 0.0):
                            radius = 1.0
                scanSpeed = ((40000000.0 / myitem.scanResolution) / (math.log((radius + math.sqrt(((radius * radius) + 1)))) ** 2.0))
            if (scanSpeed is None):
                scanSpeed = 2000
                uix.LogWarn(('GetScanSpeed returned the defauly scanspeed of %s ms ... missing scanResolution?' % scanSpeed))
            return min(scanSpeed, 180000)



    def GetCaptureData(self, ballID):
        if hasattr(self, 'capturePoints'):
            return self.capturePoints.get(ballID, None)



    def OnBSDTablesChanged(self, tableDataUpdated):
        if ('dungeon.triggers' in tableDataUpdated.iterkeys()):
            if ('/jessica' in blue.pyos.GetArg()):
                bp = self.michelle.GetBallpark()
                objectList = []
                for slimItem in self.scenarioMgr.GetDunObjects():
                    ball = bp.GetBall(slimItem.itemID)
                    if ball:
                        objectList.append((ball, slimItem))

                self.DoBallsAdded(objectList, ignoreAsteroids=0)




